import dagre from 'dagre';
import type { UniversalFlowNode, UniversalFlowEdge } from '@/models/universalFlow';
import { calculateDagreLayout } from '../utils/dagreUniversalLayoutUtils';
import type { DagreAlign, DagreRanker } from '../stores/universalVisualizerSettingsStore';

// Define layout options for extensibility
export interface LayoutOptions {
    algorithm: 'dagre' | 'elk'; // Add 'elk' later
    direction: 'TB' | 'LR'; // Dagre uses rankdir
    nodeSpacing: number; // Dagre uses nodesep
    layerSpacing: number; // Dagre uses ranksep
    align?: DagreAlign; // ADD align (optional)
    ranker?: DagreRanker; // ADD ranker (optional)
    // Add ELK-specific options here later if needed
}

// Define the result structure
export interface LayoutResult {
    nodes: UniversalFlowNode[];
    edges: UniversalFlowEdge[];
}

/**
 * Calculates the layout for the given nodes and edges based on the specified options.
 * Delegates to specific layout functions based on the algorithm.
 *
 * @param allNodes All universal flow nodes.
 * @param allEdges All universal flow edges.
 * @param options Layout configuration including algorithm and settings.
 * @returns An object with the layouted visible universal nodes and edges.
 */
export function calculateLayout(
    allNodes: UniversalFlowNode[],
    allEdges: UniversalFlowEdge[],
    options: LayoutOptions
): LayoutResult {
    console.log(`[LayoutService] Received layout request with options:`, options);
    switch (options.algorithm) {
        case 'dagre':
            // Call the imported function
            console.log(`[LayoutService] Delegating to calculateDagreLayout...`);
            return calculateDagreLayout(
                allNodes,
                allEdges,
                options.direction,
                options.nodeSpacing,
                options.layerSpacing,
                options.align,
                options.ranker
            );
        case 'elk':
            // Placeholder for ELK implementation
            console.warn("[LayoutService] ELK layout algorithm not yet implemented.");
            // Return visible nodes as fallback, potentially without positions or with default positions
            const visibleNodes = allNodes.filter(n => !n.hidden);
            const visibleNodeIds = new Set(visibleNodes.map(n => n.id));
            const visibleEdges = allEdges.filter(e => visibleNodeIds.has(e.source) && visibleNodeIds.has(e.target));
            return { nodes: visibleNodes, edges: visibleEdges };
        default:
            console.warn(`[LayoutService] Unsupported layout algorithm: ${(options as any).algorithm}. Defaulting to Dagre.`);
            // Default to Dagre if algorithm is unknown
            return calculateDagreLayout(
                allNodes,
                allEdges,
                options.direction,
                options.nodeSpacing,
                options.layerSpacing,
                options.align,
                options.ranker
             );
    }
}

// Optional: Export the service as an object if preferred
// export const universalLayoutService = {
//   calculateLayout
// };
